package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	"github.com/asters1/goquery"
	"github.com/asters1/tools"
)

// var BASE_PATH string
var wg sync.WaitGroup
var ch chan int

func GetBookUrl() []map[string]string {
	book_url := "https://mp.weixin.qq.com/s?__biz=MzU2MjM5ODQ5OA==&mid=2247551565&idx=2&sn=576a67757b44e759a4de09623530af32&chksm=fd4b5d3d374b96e272057929f94cfd41dc3e14139c58a4a2f9169f3575cb260c3b2905c8e3e7&mpshare=1&srcid=0918qWq4VSZNCTQy5jX8LLta&sharer_shareinfo=6b7b39a911937af700a880e9a12fb789&sharer_shareinfo_first=6b7b39a911937af700a880e9a12fb789&from=singlemessage&scene=1&subscene=10000&sessionid=1758176179&clicktime=1758199260&enterid=1758199260&ascene=1&fasttmpl_type=0&fasttmpl_fullversion=7912993-zh_CN-zip&fasttmpl_flag=0&realreporttime=1758199260907&devicetype=android-34&version=28003d31&nettype=WIFI&abtest_cookie=AAACAA%3D%3D&lang=zh_CN&countrycode=CN&exportkey=n_ChQIAhIQUT5%2FIkH39TUHL%2F9VYSsJrxL2AQIE97dBBAEAAAAAAGCOI1QbbpkAAAAOpnltbLcz9gKNyK89dVj0HM%2Fs5jI%2B3bMm2MYdZaD9SxcOjSMqBtSQUoFy6WtGm0FmvGxrrJ5ZIj9l7bFxmJeg%2BdsBYIr3BKvgyshFt0QoThRS3MwT2wFhetfcyn6jpqOGhBc7JNSyHnrWoVTMkUp%2FyHt9MpdUmR7%2F65R5KIG%2BgZJo%2Btr9GMqkVcRLdy8C4IWIsJl7qatHdwwoejf%2BP70TEvxDbb%2FqN9G8OHGadpn2WmZ7SbMkiYQmyuehMbiZ7p0rVAtu4lWXX%2BD1F1HmjWaouQtOQ%2BK0ZQDv%2F0WOOWEwRw%3D%3D&pass_ticket=WyCrJgIUqz8LmtgscxuTnpVZkAsIS1v%2B6QKK%2BLUfxlPzTnDe6AyNyXPmdsw5uq9x&wx_header=3"
	// fmt.Println(book_url)

	html := tools.RequestClient(book_url, "get", "", "")
	doc, _ := goquery.NewDocumentFromReader(strings.NewReader(html))
	content := doc.Find("#js_content .normal_text_link")
	res := []map[string]string{}
	content.Each(func(i int, s *goquery.Selection) {
		u, _ := s.Attr("href")
		b := map[string]string{
			"name": s.Text(),
			"url":  u,
		}
		res = append(res, b)

	})
	return res

}
func getCurrentFilePath() string {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		return ""
	}
	return filepath.Dir(filename)
}
func Mkdir(dir_path string) {
	// dir_path = getCurrentFilePath() + "\\" + dir_path
	dir_path = format_book_name(dir_path)
	if !check_file_IsNotExist(dir_path) {
		e := os.MkdirAll(dir_path, 0755)
		if e != nil {
			fmt.Println(e)
			fmt.Println(dir_path + "创建失败!")
			os.Exit(1)
		} else {
			fmt.Println(dir_path + "创建成功!")
		}

		return
	}
	fmt.Println(dir_path + "文件夹存在，无需创建!")
}

func format_book_name(name string) string {
	name = "m6/" + name

	name = strings.ReplaceAll(name, "|", "_")
	return name

}
func check_file_IsNotExist(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		fmt.Println(path + "文件存在!")
		return true
	}
	if os.IsNotExist(err) {
		fmt.Println(path + "文件不存在!")
		return false
	}
	fmt.Println(path + "文件不存在!")
	return false

}
func W_file(file_path_name string, content string) {
	file, err := os.OpenFile(file_path_name, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println(file_path_name + "打开失败！")
		return
	}
	defer file.Close()
	file.WriteString(content)
}
func RequestClient(URL string, METHOD string, HEADER string, DATA string) (string, error) {
	HeaderMap := tools.FormatStr(HEADER)
	DataMap := tools.FormatStr(DATA)
	client := &http.Client{}
	if METHOD == "get" {
		METHOD = http.MethodGet
	} else if METHOD == "post" {
		METHOD = http.MethodPost
	}
	FormatData := ""
	for i, j := range DataMap {
		FormatData = FormatData + i + "=" + j + "&"
	}
	if FormatData != "" {
		FormatData = FormatData[:len(FormatData)-1]
	}
	requset, e := http.NewRequest(
		METHOD,
		URL,
		strings.NewReader(FormatData),
	)
	if e != nil {
		fmt.Println(`
    创建NewRequest出错!
	  requset, e := http.NewRequest(
		METHOD,
		URL,
		strings.NewReader(FormatData),
	)
    `)
		fmt.Println(e)
		return "", e

	}
	if METHOD == http.MethodPost && requset.Header.Get("Content-Type") == "" {
		requset.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}
	requset.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.71 Safari/537.36")
	for i, j := range HeaderMap {
		requset.Header.Set(i, j)
	}
	resp, e := client.Do(requset)
	if e != nil {
		fmt.Println(`
    client运行出错!
	  resp, e := client.Do(requset)
    `)
		fmt.Println(e)
		return "", e

	}
	body_bit, e := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if e != nil {
		fmt.Println(`
    读取响应体出错!
	  body_bit, e := ioutil.ReadAll(resp.Body)
    `)
		fmt.Println(e)
		return "", e

	}
	return string(body_bit), nil
}

func Go_Request(URL string, book_path string, book_name string) {
	error_num := 4
	res := ""
	var e error = nil

	for i := 0; i < error_num; i++ {

		res, e = RequestClient(URL, "get", "", "")
		if e == nil {
			// fmt.Println("跳出循环")
			// fmt.Println(i)
			break
		}
	}

	W_file(format_book_name(book_path), res)
	fmt.Println(book_name + "下载完成!")
	<-ch
	wg.Done()
}
func main() {
	// BASE_PATH = "./"
	ch = make(chan int, 4)
	book_urls := GetBookUrl()
	// fmt.Println(book_urls[0]["name"])
	for i := 58; i < len(book_urls); i++ {
		// i = len(book_urls) - 1
		fmt.Println(book_urls[i]["name"])
		fmt.Println(i)
		Mkdir(book_urls[i]["name"])
		html := tools.RequestClient(book_urls[i]["url"], "get", "", "")
		doc, _ := goquery.NewDocumentFromReader(strings.NewReader(html))
		content := doc.Find("#js_content .js_editor_audio")
		content.Each(func(j int, s *goquery.Selection) {
			book_name, _ := s.Attr("name")
			fid, _ := s.Attr("voice_encode_fileid")
			voice_url := "https://res.wx.qq.com/voice/getvoice?mediaid=" + fid
			wg.Add(1)
			fmt.Println("正在下载-->" + book_name)
			fmt.Println(voice_url)
			go Go_Request(voice_url, book_urls[i]["name"]+"/"+book_name+".mp3", book_name)
			ch <- 10
		})

		wg.Wait()
	}

}
